<template>
  <div class="clearfix">
    <a-upload
      :listType="listType"
      :multiple="multiple"
      :action="uploadUrl"
      :headers="headers"
      :data="formData"
      v-model:fileList="uploadFileList"
      :beforeUpload="beforeUpload"
      :disabled="disabled"
      @change="handleChange"
      @preview="handlePreview"
    >
      <div v-if="uploadVisible">
        <div v-if="listType == 'picture-card'">
          <LoadingOutlined v-if="loading" />
          <UploadOutlined v-else />
          <div class="ant-upload-text">{{ text }}</div>
        </div>
        <a-button v-if="listType == 'picture'" :disabled="disabled">
          <UploadOutlined />
          {{ text }}
        </a-button>
      </div>
    </a-upload>
    <a-modal :open="previewOpen" :footer="null" @cancel="handleCancel()">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>
<script lang="ts">
  import { defineComponent, PropType, ref, reactive, watchEffect, computed, watch } from "vue"
  import { LoadingOutlined, UploadOutlined } from "@ant-design/icons-vue"
  import { useRuleFormItem } from "/@/hooks/component/useFormItem"
  import { propTypes } from "/@/utils/propTypes"
  import { useAttrs } from "/@/hooks/core/useAttrs"
  import { useMessage } from "/@/hooks/web/useMessage"
  import { getFileAccessHttpUrl, getRandom } from "/@/utils/common/compUtils"
  import { getAccessToken } from "/@/utils/cache/module/iam"
  import { useGlobSetting } from "/@/hooks/setting"
  import { useUserStore } from "/@/store/modules/user"
  import { ResultEnum, RequestHeaderEnum } from "/@/enums/httpEnum"
  import * as fileApi from "/@/api/infra/file"

  const globSetting = useGlobSetting()

  const { createMessage, createErrorModal } = useMessage()
  const userStore = useUserStore()
  const uploadUrl = ref('/upload')
  export default defineComponent({
    name: "MyImageUpload",
    components: { LoadingOutlined, UploadOutlined },
    inheritAttrs: false,
    props: {
      //绑定值
      value: propTypes.oneOfType([propTypes.string, propTypes.array]),
      //按钮文本
      listType: {
        type: String,
        required: false,
        default: "picture-card",
      },
      //按钮文本
      text: {
        type: String,
        required: false,
        default: "上传",
      },
      // 业务类型
      bizType: {
        type: String,
        required: false,
      },
      //这个属性用于控制文件上传的业务路径
      bizPath: {
        type: String,
        required: false,
        default: "temp",
      },
      //是否禁用
      disabled: {
        type: Boolean,
        required: false,
        default: false,
      },
      //上传数量
      fileMax: {
        type: Number,
        required: false,
        default: 1,
      },
    },
    emits: ["options-change", "change", "update:value"],
    setup(props, { emit, refs }) {
      const emitData = ref<any[]>([])
      const attrs = useAttrs()
      const formData = ref()
      const [state] = useRuleFormItem(props, "value", "change", emitData)
      //获取文件名
      const getFileName = (path) => {
        if (path.lastIndexOf("\\") >= 0) {
          let reg = new RegExp("\\\\", "g")
          path = path.replace(reg, "/")
        }
        return path.substring(path.lastIndexOf("/") + 1)
      }
      //token

      const headers = ref<object>({})
      headers.value[RequestHeaderEnum.ORIGIN_ENDPOINT] = globSetting.originEndpoint

      //上传状态
      const loading = ref<boolean>(false)
      //是否是初始化加载
      const initTag = ref<boolean>(true)
      //文件列表
      let uploadFileList = ref<any[]>([])
      //预览图
      const previewImage = ref<string | undefined>("")
      //预览框状态
      const previewOpen = ref<boolean>(false)

      //计算是否开启多图上传
      const multiple = computed(() => {
        return props["fileMax"] > 1
      })

      //计算是否可以继续上传
      const uploadVisible = computed(() => {
        return uploadFileList.value.length < props["fileMax"]
      })

      /**
       * 监听value变化
       */
      watch(
        () => props.value,
        (val, prevCount) => {
          if (val instanceof Array) {
            val = val.join(",")
          }
          if (initTag.value == true) {
            initFileList(val)
          }
        }
      )

      /**
       * 初始化文件列表
       */
      function initFileList(paths) {
        if (!paths || paths.length == 0) {
          uploadFileList.value = []
          return
        }
        let files = []
        let arr = paths.split(",")
        arr.forEach((value) => {
          let url = getFileAccessHttpUrl(value)
          files.push({
            uid: getRandom(10),
            name: getFileName(value),
            status: "done",
            url: url,
            response: {
              status: "history",
              message: value,
            },
          })
        })
        uploadFileList.value = files
      }

      /**
       * 上传前校验
       */
      async function beforeUpload(file) {
        let contentType = file.type
        console.log('file', file)
        if (contentType.indexOf("image") < 0) {
          createMessage.info("请上传图片")
          return false
        }
        const uploadToken = await fileApi.getUploadToken({
          contentType: contentType,
          size: file.size,
          name: file.name,
          bizType: props.bizType,
        })
        formData.value = uploadToken.formData
        uploadUrl.value = uploadToken.host
        file.uploadToken = uploadToken
      }
      /**
       * 文件上传结果回调
       */
      function handleChange({ file, fileList, event }) {
        initTag.value = false
        uploadFileList.value = fileList

        console.info('handleChange.file', file)
        if (file.status === "error") {
          // createMessage.error(`${file.name} 上传失败.`);
          createMessage.error(`${file.name} 上传失败，请重试`)
          return
        }

        let fileUrls = []
        //上传完成
        if (file.status != "uploading") {
          fileList.forEach((file) => {
            if (file.status === "done") {
              fileUrls.push(file.uploadToken.url)
            }
          })
          if (file.status === "done" && (file.error && file.error.status !== 200)) {
            createMessage.error(`${file.name} 上传失败，请重试`)
            return
          }
          if (file.status === "removed") {
            handleDelete(file)
          }
          file.status == "done" && createMessage.success('上传成功')
        }
        // emitData.value = fileUrls.join(',');
        state.value = fileUrls.join(",")
        emit("update:value", fileUrls.join(","))
      }

      /**
       * 删除图片
       */
      function handleDelete(file) {
        //如有需要新增 删除逻辑
        console.log(file)
      }

      /**
       * 预览图片
       */
      function handlePreview(file) {
        previewImage.value = file.url || file.thumbUrl
        previewOpen.value = true
      }

      function getAvatarView() {
        if (uploadFileList.value.length > 0) {
          let url = uploadFileList.value[0].url
          return getFileAccessHttpUrl(url, null)
        }
      }

      function handleCancel() {
        previewOpen.value = false
      }

      return {
        state,
        attrs,
        previewImage,
        previewOpen,
        uploadFileList,
        formData,
        multiple,
        headers,
        loading,
        uploadUrl,
        beforeUpload,
        uploadVisible,
        handlePreview,
        handleCancel,
        handleChange,
      }
    },
  })
</script>
<style scoped>
  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }
</style>
